package com.abou.connector.dao.impl;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.abou.connector.dao.IGenericDao;
import com.abou.utils.common.BeanUtils;

/**
 * @see IGenericDao
 * @param <T> The entity that is managed by the DAO
 */
@Repository
@Transactional(propagation = Propagation.MANDATORY)
public abstract class GenericDaoImpl<T> implements IGenericDao<T> {
  
  /**
   * The owner attribute name
   */
  protected static final String OWNER_ATT = "owner";
  
  /**
   * The parameterized <T> type handled by the DAO.
   */
  protected Class<?> tType = null;
  
  @PersistenceContext
  protected EntityManager entityManager;
  
  /**
   * The empty constructor
   */
  public GenericDaoImpl() {

    super();
    tType = BeanUtils.getParameterizedTypeFromSuperClass(getClass(), 0);
  }
  
  /**
   * @see com.abou.connector.dao.IGenericDao#create(java.lang.Object)
   */
  public void create(Object object) {

    entityManager.persist(object);
    entityManager.flush();
  }
  
  /**
   * @see com.abou.connector.dao.IGenericDao#find(java.lang.Object)
   */
  @SuppressWarnings("unchecked")
  public T find(Object id) {

    return (T) entityManager.find(tType, id);
  }
  
  /**
   * @see com.abou.connector.dao.IGenericDao#delete(java.lang.Object)
   */
  public void delete(Object entity) {

    entityManager.remove(entity);
    entityManager.flush();
  }
  
  /**
   * @see com.abou.connector.dao.IGenericDao#merge(java.lang.Object)
   */
  public void merge(Object entity) {

    entityManager.merge(entity);
  }
}
